/**
 * 实现角色基类
 * 创建者：Carburn Ashroom
 * 2024.1.1
 */

package Char;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class Char {     // Char类是一个可移动的角色

    private final Dimension screen;
    private final BufferedImage rImage;
    private final BufferedImage lImage;
    private final Rectangle rect;
    private final int speed;
    private boolean towardRight;

    public Char(String im, Point pos, int w, boolean tr, int sp, Dimension scrn) throws IOException {
        BufferedImage image = ImageIO.read(new File(im));
        screen = scrn;
        int h = w * image.getHeight() / image.getWidth();
        rect = new Rectangle(pos, new Dimension(w, h));
        speed = sp;
        towardRight = tr;
        if (tr) {
            rImage = image;
            lImage = mirror(image);
        } else {
            lImage = image;
            rImage = mirror(image);
        }
    }

    public void draw(BufferedImage p) {     // 绘制
        Graphics2D g = (Graphics2D) p.getGraphics();
        BufferedImage image = (towardRight) ? rImage : lImage;
        g.drawImage(image, rect.x, rect.y, rect.width, rect.height, null);
    }

    protected void move(Point pos) {     // 移动到指定位置
        if (pos.x > rect.x) {
            towardRight = true;
        } else if (pos.x < rect.x) {
            towardRight = false;
        }
        rect.setLocation(pos);
        ctrlOverflow();
    }

    protected int getSpeed() {
        return speed;
    }

    protected Point getPos() {
        return rect.getLocation();
    }

    protected boolean intersects(Char other) {      // 碰撞检测
        Rectangle or = other.rect;
        return !(rect.x > or.x+or.width || rect.y > or.y+or.height || rect.x+rect.width < or.x || rect.y+rect.height < or.y);
    }

    protected void walkCenterTo(Char c) {
        walkCenterTo(c.rect.getCenterX(), c.rect.getCenterY());
    }

    protected void walkCenterTo(double x, double y) {       // 向指定位置移动中心
        double distX = x - rect.getCenterX();
        double distY = y - rect.getCenterY();
        double distance = Math.sqrt(distX*distX+distY*distY);
        if (distance < Sheep.SPEED) {
            return;
        }
        runX((int)(distX*speed/distance));
        runY((int)(distY*speed/distance));
    }

    private static BufferedImage mirror(BufferedImage image) {      // 水平翻转图像
        BufferedImage newI = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_INT_ARGB);
        for (int i=0; i!=image.getWidth(); ++i) {
            for (int j=0; j!=image.getHeight(); ++j) {
                newI.setRGB(image.getWidth()-i-1, j, image.getRGB(i, j));
            }
        }
        return newI;
    }

    private void ctrlOverflow() {       // 防止出界
        if (rect.x + rect.width > screen.width) {
            rect.setLocation(screen.width-rect.width, rect.y);
        }
        if (rect.y + rect.height > screen.height) {
            rect.setLocation(rect.x, screen.height-rect.height);
        }
        if (rect.x < 0) {
            rect.setLocation(0, rect.y);
        }
        if (rect.y < 0) {
            rect.setLocation(rect.x, 0);
        }
    }

    private void runX(int offset) {     // 横向移动指定位移
        towardRight = offset > 0;
        rect.translate(offset, 0);
        ctrlOverflow();
    }

    private void runY(int offset) {     // 纵向移动指定位移
        rect.translate(0, offset);
        ctrlOverflow();
    }

}
